package com.xuelang.pipeline.infrastructure.pipeline.repository;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuelang.pipeline.client.common.result.PageRecord;
import com.xuelang.pipeline.client.pipeline.dto.PipelineQuery;
import com.xuelang.pipeline.domain.pipeline.Pipeline;
import com.xuelang.pipeline.domain.pipeline.repository.PipelineRepository;
import com.xuelang.pipeline.infrastructure.pipeline.converter.PipelineToPipelineDOConverter;
import com.xuelang.pipeline.infrastructure.pipeline.dataobject.PipelineDO;
import com.xuelang.pipeline.infrastructure.pipeline.mapper.PipelineMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 流水线仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class PipelineRepositoryImpl implements PipelineRepository {

    @Autowired
    PipelineMapper pipelineMapper;

    @Override
    public PageRecord<Pipeline> pageList(long currentPage, long pageSize, PipelineQuery pipelineQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<PipelineDO> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<PipelineDO> wrapper = Wrappers.lambdaQuery(PipelineDO.class);
        if (pipelineQuery != null) {
            // 根据流水线编码过滤
            if (StringUtils.isNotBlank(pipelineQuery.getCode())) {
                wrapper.eq(PipelineDO::getCode, pipelineQuery.getCode());
            }
            // 根据流水线编码数组过滤
            if (CollectionUtil.isNotEmpty(pipelineQuery.getCodeList())) {
                wrapper.in(PipelineDO::getCode, pipelineQuery.getCodeList());
            }
            // 根据流水线名称模糊查询
            if (StringUtils.isNotBlank(pipelineQuery.getName())) {
                wrapper.like(PipelineDO::getName, pipelineQuery.getName());
            }
            // 根据流水线所属项目编码过滤
            if (StringUtils.isNotBlank(pipelineQuery.getProjectCode())) {
                wrapper.eq(PipelineDO::getProjectCode, pipelineQuery.getProjectCode());
            }
            // 根据所属环境uuid进行过滤
            if (StringUtils.isNotBlank(pipelineQuery.getEnvironmentUuid())) {
                wrapper.eq(PipelineDO::getEnvironmentUuid, pipelineQuery.getEnvironmentUuid());
            }
            // 根据所属应用编码进行过滤
            if (StringUtils.isNotBlank(pipelineQuery.getApplicationCode())) {
                wrapper.like(PipelineDO::getApplicationCode, pipelineQuery.getApplicationCode());
            }
            if (StringUtils.isNotBlank(pipelineQuery.getTag())) {
                wrapper.eq(PipelineDO::getTag, pipelineQuery.getTag());
            }
        }
        pipelineMapper.selectPage(page, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords().stream().map(PipelineToPipelineDOConverter.INSTANCE::pipelineDOToPipeline).collect(Collectors.toList())
        );
    }

    @Override
    public List<Pipeline> list(PipelineQuery pipelineQuery) {
        LambdaQueryWrapper<PipelineDO> wrapper = Wrappers.lambdaQuery(PipelineDO.class);
        if (pipelineQuery != null) {
            if (StringUtils.isNotBlank(pipelineQuery.getCode())) {
                wrapper.eq(PipelineDO::getCode, pipelineQuery.getCode());
            }
            if (StringUtils.isNotBlank(pipelineQuery.getName())) {
                wrapper.like(PipelineDO::getName, pipelineQuery.getName());
            }
            if (StringUtils.isNotBlank(pipelineQuery.getProjectCode())) {
                wrapper.eq(PipelineDO::getProjectCode, pipelineQuery.getProjectCode());
            }
            if (StringUtils.isNotBlank(pipelineQuery.getEnvironmentUuid())) {
                wrapper.eq(PipelineDO::getEnvironmentUuid, pipelineQuery.getEnvironmentUuid());
            }
            if (StringUtils.isNotBlank(pipelineQuery.getApplicationCode())) {
                wrapper.like(PipelineDO::getApplicationCode, pipelineQuery.getApplicationCode());
            }
            if (StringUtils.isNotBlank(pipelineQuery.getTag())) {
                wrapper.eq(PipelineDO::getTag, pipelineQuery.getTag());
            }
        }
        return pipelineMapper.selectList(wrapper).stream()
                .map(PipelineToPipelineDOConverter.INSTANCE::pipelineDOToPipeline).collect(Collectors.toList());
    }


    @Override
    public Boolean save(Pipeline pipeline) {
        return pipelineMapper.insert(PipelineToPipelineDOConverter.INSTANCE.pipelineToPipelineDO(pipeline)) == 1;
    }

    @Override
    public Boolean update(Pipeline pipeline) {
        return pipelineMapper.update(
                PipelineToPipelineDOConverter.INSTANCE.pipelineToPipelineDO(pipeline),
                Wrappers.lambdaQuery(PipelineDO.class).eq(PipelineDO::getCode, pipeline.getCode())) == 1;
    }

    @Override
    public Boolean delete(String code) {
        return pipelineMapper.delete(Wrappers.lambdaQuery(PipelineDO.class).eq(PipelineDO::getCode, code)) == 1;
    }

    @Override
    public Pipeline query(String code) {
        PipelineDO pipelineDO = pipelineMapper.selectOne(Wrappers.lambdaQuery(PipelineDO.class).eq(PipelineDO::getCode, code));
        return PipelineToPipelineDOConverter.INSTANCE.pipelineDOToPipeline(pipelineDO);
    }

    @Override
    public List<Pipeline> queryByComponentLabel(String componentLabel) {
        List<PipelineDO> pipelineDOList = pipelineMapper.selectList(Wrappers.lambdaQuery(PipelineDO.class).eq(PipelineDO::getComponentLabel, componentLabel));
        return pipelineDOList.stream().map(PipelineToPipelineDOConverter.INSTANCE::pipelineDOToPipeline).collect(Collectors.toList());
    }

    @Override
    public List<Pipeline> list(Pipeline pipeline) {
        List<PipelineDO> pipelineDOS = pipelineMapper
                .selectList(Wrappers.lambdaQuery(PipelineDO.class)
                        .eq(StringUtils.isNotBlank(pipeline.getComponentLabel()), PipelineDO::getComponentLabel, pipeline.getComponentLabel())
                        .eq(StringUtils.isNotBlank(pipeline.getEnvironmentUuid()), PipelineDO::getEnvironmentUuid, pipeline.getEnvironmentUuid()));
        return pipelineDOS.stream().map(PipelineToPipelineDOConverter.INSTANCE::pipelineDOToPipeline).collect(Collectors.toList());
    }

    @Override
    public Boolean existsByEnvironmentUuid(String environmentUuid) {
        return pipelineMapper.exists(Wrappers.lambdaQuery(PipelineDO.class).eq(PipelineDO::getEnvironmentUuid, environmentUuid));
    }

    @Override
    public Boolean existsCode(String pipelineCode) {
        return pipelineMapper.exists(Wrappers.lambdaQuery(PipelineDO.class).eq(PipelineDO::getCode, pipelineCode));
    }

    @Override
    public Boolean existsName(String pipelineCode, String pipelineName) {
        List<PipelineDO> pipelineDOS = pipelineMapper.selectList(Wrappers.lambdaQuery(PipelineDO.class).eq(PipelineDO::getName, pipelineName));
        if (ObjectUtil.isEmpty(pipelineDOS)) {
            return false;
        }
        return pipelineDOS.stream().anyMatch(pipelineDO -> !ObjectUtil.equals(pipelineCode, pipelineDO.getCode()));
    }
}
